#pragma once
#define _REGISTER_NBT_GET(type, typeName) type Get##typeName();
#define _REGISTER_NBTT(type, typeName)  _REGISTER_NBT_GET(type, typeName);void Set##typeName(type type##Value);
#define _IMPLEMENT_NBTT(type, typeName) \
	type NBT::Get##typeName() { return (*(type*)m_pData.get()); }; \
	void NBT::Set##typeName(type type##Value) { memcpy(m_pData.get(), &type##Value, sizeof(type)); };
#include <vector>
#include <string>
#include <boost\smart_ptr\shared_ptr.hpp>
typedef boost::shared_ptr<char> NBTData;
using namespace std;
class NBT
{
public:
	static const int nbtVersion;
public:
	NBT(void);
	~NBT(void);
	_REGISTER_NBTT(int, Int);
	_REGISTER_NBTT(double, Double);
	_REGISTER_NBTT(float, Float);
	_REGISTER_NBTT(char, Byte);
	_REGISTER_NBTT(string, String);
	void* GetListData();
	void SetListData(void *pData, int dataType, int nCount);
	int GetListType();
	int GetListCount();
	int GetListLength();
	int GetCompoundCount();
	int GetCompoundLength();
	void AddCompoundElement(NBT element);
	void ClearCompoundElements();
	void SetType(int type);
	int GetType();
	int GetNBTSize();
private:
	vector<NBT> m_compoundTags;
	int m_nTagType;
	string m_strName;
	NBTData m_pData;
};